/**
 * Copyright (c) 2021 sdpjw Inc. All rights reserved.
 */
package com.lmn.oval;

import net.sf.oval.ValidationCycle;
import net.sf.oval.configuration.annotation.AbstractAnnotationCheck;
import net.sf.oval.exception.OValException;

/**
 * @version 4.0
 * @describe:
 * @author: houkai
 * @Date: 2021/06/03
 */
public class OrgNoCheckImpl extends AbstractAnnotationCheck<OrgNoCheck> {
    private static final String SPLIT = "-";

    private boolean notNull;

    /**
     * 加权因子
     */
    private static final int[] power = {3, 7, 9, 10, 5, 8, 4, 2};

    @Override
    public void configure(OrgNoCheck orgNoCheck) {
        super.configure(orgNoCheck);
    }

    public void setNotNull(boolean notNull) {
        this.notNull = notNull;
    }

    /**
     * 判断组织机构编号是否有效
     *
     * @param validatedObject 进入校验器的对象
     * @param valueToValidate 注解当前标注的属性值
     * @return 是否通过验证
     * @throws OValException OValException
     */
    @Override
    public boolean isSatisfied(final Object validatedObject, final Object valueToValidate, final ValidationCycle cycle) throws OValException {
        if (validatedObject == null) {
            return false;
        }
        String value = (String) valueToValidate;
        String temp = value.toUpperCase();
        if (temp.contains(SPLIT)) {
            temp = temp.replace("-", "");
        }
        if (temp.length() != 9) {
            return false;
        }
        // 获取前面8位
        String pre8 = temp.substring(0, 8);
        // 0~z;
        char[] pre8chars = pre8.toCharArray();
        // 获取校验码
        String code = temp.substring(8, 9);
        return isCode(code, sum(pre8chars));
    }


    /**
     * 求和
     */
    private static int sum(char[] bit) {
        int sum = 0;
        for (int i = 0; i < bit.length; i++) {
            int intTemp = bit[i] > '9' ? (bit[i] - 'A' + 10) : Integer.parseInt(bit[i] + "");
            sum += intTemp * power[i];
        }
        return sum;
    }

    /**
     * 判断机构代码的校验码和计算出的校验码是否一致
     */
    private static boolean isCode(String a, int b) {
        String codetemp = (11 - b % 11) == 10 ? "X" : (11 - b % 11) == 11 ? 0 + "" : (11 - b % 11) + "";
        return a.equals(codetemp);
    }
}
